import { getRouters } from '@/api/system/menu'
import { asyncRoutes, constantRoutes } from '@/router'
import { defineStore } from 'pinia'
import { ref } from 'vue'
import Layout from '@/layout/index.vue'

// 匹配src里面所有的vue文件
const modules = import.meta.glob('@/**/index.vue')

export const usePermissionStore = defineStore('permission', () => {
    const routes = ref([])
    function generateRoutes(roles, permissions) {
        return new Promise((resolve, reject) => {
            getRouters().then((res) => {
                let accessedRoutes = []
                try {
                    accessedRoutes = filterAsyncRoutes(asyncRoutes, roles, permissions)
                    //后台接口已经对用户权限进行了校验,从后台获取对路由信息不需要再做权限校验
                    const backendReturnRoutes = convertRoutes(res.data)
                    addNotFound(backendReturnRoutes)
                    accessedRoutes = [...accessedRoutes, ...backendReturnRoutes]
                    routes.value = [...constantRoutes, ...accessedRoutes]
                    resolve(accessedRoutes)
                } catch (error) {
                    reject(error)
                }
            })
        })
    }
    return { routes, generateRoutes }
})
/**
 * 为后端返回的路由追加404组件,以确保404通配组件是最后一个路由,否则它之后的路由都会先匹配到它,导致无法显示它之后的路由
 * @param {array} backendReturnRoutes
 */
function addNotFound(backendReturnRoutes) {
    const not_found_vue = import.meta.glob('@/views/error-page/404.vue')
    const not_found = {
        path: '/:pathMatch(.*)*',
        component: not_found_vue[Object.keys(not_found_vue)[0]],
        hidden: true
    }
    backendReturnRoutes.push(not_found)
}

/**
 * 把后端返回的组件名称替换为真实的组件
 * @param {array} _routes 路由对象
 */
function convertRoutes(_routes) {
    _routes.forEach((_route) => {
        // 删除属性
        delete _route.id
        delete _route.alwaysShowDesc
        delete _route.hiddenDesc
        delete _route.parentId
        if (_route.meta) {
            delete _route.meta.noCacheDesc
            delete _route.meta.affixDesc
            delete _route.meta.breadcrumbDesc
        }
        if (_route.component) {
            if (_route.component === 'layout') {
                _route.component = Layout
            } else {
                for (const path in modules) {
                    if (_route.component && path && path.includes(_route.component)) {
                        _route.component = modules[path]
                        break
                    }
                }
            }
        }
        if (_route.children) {
            convertRoutes(_route.children)
        }
    })
    return _routes
}
/**
 * 验证当前用户是否有权限
 * @param {array} roles 用户角色
 * @param {array} permissions 用户权限
 * @param {array} route  路由对象
 * @returns
 */
function hasPermission(roles, permissions, route) {
    if (route.meta && route.meta.roles && route.meta.permissions) {
        return (
            roles.some((role) => route.meta.roles.includes(role)) &&
            permissions.some((permission) => route.meta.permissions.includes(permission))
        )
    } else if (route.meta && route.meta.roles) {
        return roles.some((role) => route.meta.roles.includes(role))
    } else if (route.meta && route.meta.permissions) {
        return permissions.some((permission) => route.meta.permissions.includes(permission))
    } else {
        return true
    }
}

/**
 * 按递归过滤异步路由表
 * @param routes asyncRoutes
 * @param roles 用户角色
 * @param permissions 用户权限
 */
function filterAsyncRoutes(routes, roles, permissions) {
    const res = []
    routes.forEach((route) => {
        const tmp = {
            ...route
        }
        if (hasPermission(roles, permissions, tmp)) {
            if (tmp.children) {
                tmp.children = filterAsyncRoutes(tmp.children, roles, permissions)
            }
            res.push(tmp)
        }
    })
    return res
}
